/*
 * File:    HostMatch.java
 * Created: 01-Jan-2007
 * Version: $Id$
 *
 * COPYRIGHT (C) 2007, Bitgate Software, LLC.  All Rights Reserved.
 *
 * kenji.hollis@bitgatesoftware.com
 */

package com.bitgate.util.socket;

import java.util.ArrayList;

import com.bitgate.util.wildcard.Wildcard;

/**
 * This class calculates an allow or deny rule based on the IP address passed, and the list of IP addresses for allow and
 * deny checking.  All access methods are static.
 * <p/>
 * This code is already being used by the <code>Service</code> objects, so there is no immediate need to use this
 * code in your protocol handlers.  However, if you want to apply host allow/deny rules to your code after a connection
 * is made (say, for rules based on connection permissions), you can do that with this code.
 *
 * @author Kenji Hollis &lt;kenji@bitgatesoftware.com&gt;
 * @version $Id$
 */
public class HostMatch
{
    /**
     * Applies a rule of allowed-versus-denied address against the specified IP address.  By default, the connection is
     * denied unless it matches an entry in the allow list.  If it is allowed, it then matches the address against an
     * entry in the deny list.  If both match, or if there is a deny match at any point, this function returns a 
     * <code>false</code> indicating the connection would have been refused.  Otherwise, it returns a <code>true</code>.
     *
     * @param ipAddress The IP Address to compare.
     * @param allowList The <code>ArrayList&lt;String&gt;</code> containing a list of allowed hosts.
     * @param denyList The <code>ArrayList&lt;String&gt;</code> containing a list of denied hosts.
     * @return <code>false</code> if the IP address is denied, <code>true</code> otherwise.
     */
    public static boolean checkAllowDeny(String ipAddress, ArrayList<String> allowList, ArrayList<String> denyList)
    {
		boolean isDenied = true;
	
		for(String allowEntry : allowList) {
		    String wildcardMatch = Wildcard.toRegexp(allowEntry);
	
		    if (ipAddress.matches(wildcardMatch)) {
		    	isDenied = false;
		    	break;
		    }
		}
	
		if (isDenied) {
		    return false;
		}
	
		for(String denyEntry : denyList) {
		    String wildcardMatch = Wildcard.toRegexp(denyEntry);
	
		    if (ipAddress.matches(wildcardMatch)) {
		    	return true;
		    }
		}
	
		return !(isDenied);
    }

    /**
     * Applies a rule of denied-versus-allowed address against the specified IP address.  By default, the connection is
     * allowed unless it matches an entry in the deny list.  If it matches an entry in the deny list, it then checks the
     * same IP address against the allow list.  If the address matches the allow, then the address is allowed through,
     * otherwise, it is denied.  
     *
     * @param ipAddress The IP Address to compare.
     * @param allowList The <code>ArrayList&lt;String&gt;</code> containing a list of allowed hosts.
     * @param denyList The <code>ArrayList&lt;String&gt;</code> containing a list of denied hosts.
     * @return <code>false</code> if the IP address is denied, <code>true</code> otherwise.
     */
    public static boolean checkDenyAllow(String ipAddress, ArrayList<String> allowList, ArrayList<String> denyList)
    {
		boolean isDenied = false;
	
		for(String denyEntry : denyList) {
		    String wildcardMatch = Wildcard.toRegexp(denyEntry);
	
		    if (ipAddress.matches(wildcardMatch)) {
		    	isDenied = true;
		    	break;
		    }
		}
	
		if (!isDenied) {
		    return false;
		}
	
		for(String allowEntry : allowList) {
		    String wildcardMatch = Wildcard.toRegexp(allowEntry);
	
		    if (ipAddress.matches(wildcardMatch)) {
		    	return false;
		    }
		}
	
		return isDenied;
    }
}
